// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Diagnostics.ContractsLight;
using System.Globalization;

namespace BuildXL.Cache.Interfaces
{
    /// <summary>
    /// Failure returned when the cache gets into an inconsistent
    /// state with reguard to deterministic records (trying to replace
    /// a deterministic record with a different deterministic record)
    /// </summary>
    public class NotDeterministicFailure : CacheBaseFailure
    {
        private readonly string m_description;

        /// <summary>
        /// Deterministic cache record error
        /// </summary>
        /// <param name="cacheId">CacheId</param>
        /// <param name="oldRecord">Existing cache record</param>
        /// <param name="newRecord">Attempted new cache record</param>
        /// <remarks>
        /// This failure is raised when a cache record that is marked as
        /// deterministic is unable to be added to the cache due to a
        /// prior, non-matching record.  If the records do match then
        /// the determinism is re-affirmed and not an error.
        /// </remarks>
        public NotDeterministicFailure(string cacheId, FullCacheRecord oldRecord, FullCacheRecord newRecord)
        {
            Contract.Requires(cacheId != null);
            Contract.Requires(oldRecord != null);
            Contract.Requires(newRecord != null);

            m_description = string.Format(CultureInfo.InvariantCulture, "Cache: {0} - Deterministic record {1} has a non-matching prior value {2}", cacheId, newRecord, oldRecord);
        }

        /// <summary>
        /// Deterministic cache record error
        /// </summary>
        /// <param name="description">Pre-formatted description of error</param>
        /// <remarks>
        /// This constructor is only to be used when a NotDeterministicFailure
        /// is being propagated and the description string was previously
        /// generated by using the other constructor
        /// </remarks>
        public NotDeterministicFailure(string description)
        {
            Contract.Requires(description != null);

            m_description = description;
        }

        /// <inheritdoc/>
        public override string Describe()
        {
            return m_description;
        }
    }
}
